package com.cndw.kungfu.ext;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.cndw.commons.util.BlankUtils;
import com.cndw.kungfu.config.ConstantsConfig;

/**
 * 敏感词处理
 * 
 * @author fantadust
 * @date 2011-5-23 上午10:28:56
 */
public class WordProcesser {

	/**
	 * 敏感词ROOT节点
	 */
	private static Node badWordNode;

	/**
	 * 用来替换敏感词的符号
	 */
	public static final Character FILTER = '*';

	/**
	 * 系统禁用字
	 */
	public static final char[] illegalchars = { '~', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '+', '\\', '|', '<', '>', ',', '.', '/',
			'?', ']', '[', '{', '}', '`', '\'' };
	/**
	 * 仅中文
	 */
	public static final String only_chinese = "^[\u4e00-\u9fa5]*$";

	/**
	 * 仅英文
	 */
	public static final String only_english = "^[a-zA-Z]*$";

	/**
	 * 无符号
	 */
	public static final String no_symbol = "^[\u4e00-\u9fa5a-zA-Z0-9]*$";

	/**
	 * 脏话过滤
	 * 
	 * @param content
	 * @return
	 */
	public static String filterWorlds(String content) {

		if (BlankUtils.isBlank(badWordNode)) {
			load();
		}

		int wordCounts = 0;
		Node parentNode = badWordNode;
		char[] sources = content.toCharArray();
		char[] charactors = content.toLowerCase().toCharArray();
		for (int index = 0; index < charactors.length; index++) {
			parentNode = findChildNode(parentNode, charactors[index]);
			if (BlankUtils.isBlank(parentNode)) {
				index = index - wordCounts;
				wordCounts = 0;
				parentNode = badWordNode;
			} else {
				wordCounts++;
				if (parentNode.endPoint && !checkNextEndPoint(parentNode, charactors, index + 1)) {
					for (int i = 0; i < wordCounts; i++) {
						sources[index - i] = FILTER;
					}
					wordCounts = 0;
					parentNode = badWordNode;
				}
				if (index == (charactors.length - 1)) {
					index = index - wordCounts + 1;
					wordCounts = 0;
					parentNode = badWordNode;
				}
			}
		}

		content = new String(sources);

		Pattern pattern = Pattern.compile(ConstantsConfig.getBadWorldExp());
		Matcher m = pattern.matcher(content);
		content = m.replaceAll(FILTER.toString());

		return content;
	}

	public static boolean isAd(String content) {
		if (content == null || content.length() <= 5) {
			return false;
		}
		if (ConstantsConfig.getAdWorld() == null || ConstantsConfig.getAdWorld().size() == 0) {
			return false;
		}
		try {
			content = toAdSource(content);
			int badNum = 0;
			List<String> adsList = ConstantsConfig.getAdWorldDanger();
			for (String e : adsList) {
				if (content.indexOf(e) >= 0) {
					return true;
				}
			}
			adsList = ConstantsConfig.getAdWorld();
			for (String e : adsList) {
				if (content.indexOf(e) >= 0) {
					badNum++;
				}
				if (badNum >= 3) {
					return true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static String toAdSource(String content) {
		return StringProcesser.removeFuHao(StringProcesser.ToDBC(content.toLowerCase()));
	}

	/**
	 * 检查是否有屏蔽词
	 * 
	 * @param content
	 * @return
	 */
	public static String chkBadWorlds(String content) {

		if (BlankUtils.isBlank(badWordNode)) {
			load();
		}

		Node parentNode = badWordNode;
		StringBuilder word = new StringBuilder();
		char[] charactors = content.toLowerCase().toCharArray();
		for (int index = 0; index < charactors.length; index++) {
			parentNode = findChildNode(parentNode, charactors[index]);
			if (BlankUtils.isBlank(parentNode)) {
				index = index - word.length();
				word.delete(0, word.length());
				parentNode = badWordNode;
			} else {
				word.append(charactors[index]);
				if (parentNode.endPoint && !checkNextEndPoint(parentNode, charactors, index + 1)) {
					return word.toString();
				}
				if (index == (charactors.length - 1)) {
					index = index - word.length() + 1;
					word.delete(0, word.length());
					parentNode = badWordNode;
				}
			}
		}

		Pattern pattern = Pattern.compile(ConstantsConfig.getBadWorldExp());
		Matcher m = pattern.matcher(content);
		while (m.find()) {
			return m.group();
		}

		return null;
	}

	/**
	 * 匹配正则是否成功
	 * 
	 * @param content
	 * @param regex
	 * @return
	 */
	public static boolean chkPerg(String content, String regex) {
		Pattern pattern = Pattern.compile(regex);
		Matcher m = pattern.matcher(content);
		return m.find();
	}

	public static synchronized void load() {
		try {
			Node tmp = new Node('R');
			appendRootNode(ConstantsConfig.getBadWorld(), tmp);
			badWordNode = tmp;
		} catch (Exception e) {
			e.printStackTrace();
		}
		LogUtil.getMain().debug("reload world");
		// if (badWordNode == null) {

		// }

	}

	/**
	 * 当遇到结束点时判断是否有下一个结束点
	 * 
	 * @return
	 */
	public static boolean checkNextEndPoint(Node parentNode, char[] charactor, int index) {

		if (index == charactor.length) {
			return false;
		}

		parentNode = findChildNode(parentNode, charactor[index]);

		if (parentNode == null) {
			return false;
		}

		if (parentNode.endPoint) {
			return true;
		}

		return checkNextEndPoint(parentNode, charactor, ++index);
	}

	/**
	 * 将所有敏感词添加到根节点上
	 * 
	 * @param badwords
	 * @param rootNode
	 */
	private static void appendRootNode(List<String> badwords, Node rootNode) {
		if (!BlankUtils.isBlank(badwords)) {
			for (String badword : badwords) {
				if (!BlankUtils.isBlank(badword)) {
					char[] charactors = badword.toLowerCase().toCharArray();
					insertNode(rootNode, charactors, 0);
				}
			}
		}
	}

	/**
	 * 增加节点
	 * 
	 * @param parentNode
	 * @param charactors
	 * @param index
	 */
	private static void insertNode(Node parentNode, char[] charactors, int index) {

		Node childNode = findChildNode(parentNode, charactors[index]);

		if (childNode == null) {
			childNode = new Node(charactors[index]);
			parentNode.childNodes.add(childNode);
		}

		// 设置一个结束点
		if (index == (charactors.length - 1)) {
			childNode.endPoint = true;
		}

		index++;

		if (index < charactors.length) {
			insertNode(childNode, charactors, index);
		}
	}

	/**
	 * 查找子节点
	 * 
	 * @param parentNode
	 * @param charactor
	 * @return
	 */
	private static Node findChildNode(Node parentNode, char charactor) {
		for (Node childNode : parentNode.childNodes) {
			if (childNode.charactor == charactor) {
				return childNode;
			}
		}
		return null;
	}

	/**
	 * 节点
	 * 
	 * 
	 * @author <a href="mailto:whz-work@163.com">汪洪州</a>
	 * 
	 * @since 1.0 Create on 2011-6-15
	 */
	private static class Node {

		/**
		 * 节点字符
		 */
		public char charactor;

		/**
		 * 该节点是否是一个敏感词的结束点
		 */
		public boolean endPoint;

		/**
		 * 所有子节点
		 */
		public List<Node> childNodes = new ArrayList<Node>();

		public Node(char charactor) {
			this.charactor = charactor;
			this.endPoint = false;
		}
	}
}
